﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Scripting.AST.ObjectModel;
using IWMAG.Scripting.Types;
using IWMAG.Scripting.AST.Operators;
using IWMAG.Scripting.Interpreter;

namespace IWMAG.Scripting.AST.TerminalExpressions {
    internal class VariableExpression : CodeExpression {
        public string Name;
        protected CodeType Type;

        public VariableExpression(Compiler.Lexeme l, string var) : base(l) {
            Name = var;
        }

        public override CodeType TypeOf() {
            return Type;
        }

        public override void Verify(Helpers.CompileTable sym, List<Compiler.IUserInfo> error) {
            base.Verify(sym, error);

            if (sym.Variables.Contains(Name)) {
                Type = sym.Variables[Name];

                if (sym.Lookahead.Contains(typeof(LateBindOperator))) {
                    string s = sym.Lookahead[typeof(LateBindOperator)]() as string;
                    if (Name.Equals(s)) {
                        SendError(true, error, "Latebound variable may not self reference. Use the value keyword instead.");
                    }
                }
            } else {
                SendError(true, error, "Variable " + Name + " is not in the current scope.");
            }
        }

        public override IEnumerable<Continuation> ValueOf(Interpreter.ScriptEngine engine, Helpers.RuntimeTable sym, Interpreter.Reference<Interpreter.RunValue> val) {
            var a = sym;
            var b = a.Variables;
            var c = b[Name];
            val.ReferencedValue.Value = c;
            yield break;
        }
    }
}
